package Persistencia;

import Datatypes.DataComentario;
import Datatypes.DataJuego;
import Datatypes.DataJuegoVersion;
import Datatypes.PDate;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class BDMJuego{
    
    private static BDMJuego instance = null;
    private BDMConexion ct = null; 
    private PreparedStatement ps = null;
    private ResultSet rs = null;

    //CONSTRUCTOR
    
    private BDMJuego(){}

    //GETERS
    
    public static synchronized BDMJuego getInstance(){
        
        if(instance == null){
            
            instance = new BDMJuego();
            
        }
        
        return instance;
    
    }
    
    //SETER
    
    public void setConexion(BDMConexion BDMC){
    
        this.ct = BDMC;
    
    }
    
    //FUNCIONES PROPIAS
    
    //AREA DE TRABAJO DE JONATHAN////////////////////////////////////////////////////////////////////////////////////////////////
    
    public List<String> obtenerListaDeJuegos() throws Exception{
    
        
        
        List<String> lj = new ArrayList();
        
        try{
        
            ps = ct.getConexion().prepareStatement("SELECT nombre FROM juegos");
            rs = ps.executeQuery();
            
            while(rs.next()){
            
                lj.add(rs.getString("nombre"));
            
            }
        
        }
        
        catch(SQLException e){
        
            throw new Exception("Error al obtener la lista de juegos.<br><br>Codigo de Error: BDMJOLDJ<br>Mensaje: " + e.getMessage());
               
        }
        
        return lj;
    
    }
    
    public Integer getIDPadre(Comentario hijo) throws Exception{
    
        
        
        Integer idpadre = null;
                
        try{

            ps = ct.getConexion().prepareStatement("SELECT numero_comentario_padre FROM respuestas_de_comentarios WHERE numero_comentario_hijo = ?");
            ps.setInt(1, hijo.getNumero());
            rs = ps.executeQuery();
        
            if(rs.next()){
            
                idpadre = rs.getInt(1);
            
            }
        
        }

        catch(SQLException e){
        
            throw new Exception("Error interno!.<br><br>Codigo de Error: BDMJGIDP<br>Mensaje: " + e.getMessage());
               
        }
        
        return idpadre;
    
    }
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    // AREA DE TRABAJO DE NACHO
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso 4.<br>
     * Lista los juegos filtrados por la categoria de id_categoria = id_cat.<br>
     *
     * @return List<String>
     */
    public List<String> listaJuegosXCategoria(String cat) throws Exception{
             
        
        
        String nom;
        int id;
        List<String> listaj;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT DISTINCT j.codigo, j.nombre"
                    + " FROM juegos j, categorias_de_juegos cj, categorias c"
                    + " WHERE j.codigo = cj.codigo_juego"
                    + " AND cj.id_categoria = c.id_categoria"
                    + " AND c.nombre = ?"
                    + " ORDER BY j.nombre");
            ps.setString(1, cat);
            rs = ps.executeQuery();

            listaj = new ArrayList();
            while(rs.next()){

                id = rs.getInt(1);
                nom = rs.getString(2);
                listaj.add(id + "-" + nom);

            }
           
        }
        
        catch(Exception e){
        
            throw e;
        
        }
            
        return listaj;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso 4.<br>
     * Lista los juegos filtrados por la categoria de id_categoria = id_cat.<br>
     *
     * @return List<String>
     */
    public List<String> listaJuegosXCategoria(Integer idCat) throws Exception{
    
        
        
        String nom;
        int id;
        List<String> listaj;
         
        try{
        
            ps = ct.getConexion().prepareStatement("SELECT DISTINCT j.codigo, j.nombre"
                    + " FROM juegos j, categorias_de_juegos cj, categorias c"
                    + " WHERE j.codigo = cj.codigo_juego"
                    + " AND cj.id_categoria = c.id_categoria"
                    + " AND c.id_categoria = ?"
                    + " ORDER BY j.nombre");
            ps.setInt(1, idCat);
            rs = ps.executeQuery();

            listaj = new ArrayList();

            while(rs.next()){

                id = rs.getInt(1);
                nom = rs.getString(2);
                listaj.add(id + "-" + nom);

            }
        
        }
        
        catch(Exception e){
        
            throw e;
        
        }
        
        return listaj;       
        
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Juego.<br>
     * Obtener las categorias del juego de codigo = codigo.<br>
     *
     * @return int
     */
    public List<Categoria> listarCategoriasDeJuego(Integer codigo) throws Exception{
    
        
        
        String nom;
        List<Categoria> listaC = null;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT c.id_categoria, c.nombre "
                                   + "FROM categorias c, juegos j, categorias_de_juegos cj "
                                   + "WHERE j.codigo = ? AND cj.codigo_juego = ? "
                                   + "AND cj.id_categoria = c.id_categoria "
                                   + "ORDER BY c.nombre");
            ps.setInt(1, codigo);
            ps.setInt(2, codigo);
            rs = ps.executeQuery();
            listaC = new ArrayList();
            
            while(rs.next()){
                
                nom = rs.getString(2);
                Categoria cat = new Categoria(nom);
                cat.setId(rs.getInt(1));
                listaC.add(cat); 
            
            }
            
        }catch(SQLException e){
            
            throw new Exception("ERROR en listar las categoria de Juego.");
            
        }
        
        return listaC;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Juego.<br>
     * Obtener la cantidad de categorias existente.<br>
     *
     * @return int
     */
    public int getCantCategorias() throws Exception{
        
        
        
        int cant;
        
        try{
        
            ps = ct.getConexion().prepareStatement("SELECT COUNT(*) as cantidad FROM Categorias");
            rs = ps.executeQuery();
            cant = rs.getInt("cantidad");
            ps.executeUpdate();
        
        }
        
        catch(Exception e){
        
            throw e;
        
        }
        
        return cant;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Juego.<br>
     * Lista todas las categorias del sistema para cargar un combobox.<br>
     *
     * @return List<Categoria>
     */
    public List<Categoria> listarCategorias() throws Exception{ 
    
        
        
        String nom;
        List<Categoria> lista = null;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM categorias ORDER BY nombre");
            rs = ps.executeQuery();
            lista = new ArrayList();
            
            while(rs.next()){
                
                nom = rs.getString(2);
                Categoria cat = new Categoria(nom);
                cat.setId(rs.getInt(1));
                lista.add(cat); 
            
            }
            
        }catch(SQLException e){
            
            throw new Exception("ERROR en listar las categoria.");
            
        }
        
        return lista;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Juego.<br>
     * Obtiene el Juego de nombre = nomJuego.<br>
     *
     * @return Juego
     */
    public Juego obtenerJuego(String nomJuego) throws Exception{

        
        
        ResultSet rsCat, rsD, rsJ, rsCom;
        Juego j;
        
        try{
        
            
            
            ps = ct.getConexion().prepareStatement("SELECT * FROM juegos WHERE nombre = ?");
            ps.setString(1, nomJuego);
            rsJ = ps.executeQuery();

            
            
            //Obtengo el codigo del Juego
            int codigoJ = rsJ.getInt(4);

            
            
            //Obtengo las categorias del Juego
            ps = ct.getConexion().prepareStatement("SELECT c.id_categoria, c.nombre "
                                   + "FROM categorias_de_juegos cj, categorias c, juegos j "
                                   + "WHERE j.codigo = ? "
                                   + "AND c.id_categoria = cj.id_categoria "
                                   + "AND cj.codigo_juego = ?");

            ps.setInt(1, codigoJ);
            ps.setInt(2, codigoJ); 
            rsCat = ps.executeQuery();

            
            
            List<Categoria> listaCat = new ArrayList();

            while(rsCat.next()){

                Categoria cat = new Categoria(rsCat.getString(2));
                cat.setId(rsCat.getInt(1));
                listaCat.add(cat); 

            }

            
            //Obtengo los Comentarios del Juego
            ps = ct.getConexion().prepareStatement("SELECT c.numero, c.texto, c.fecha, c.respuesta, cc.nick_cliente "
                                   + "FROM comentarios_de_juegos cj, juegos j, comentarios c, comentarios_de_clientes cc "
                                   + "WHERE c.numero = cj.numero_comentario "
                                   + "AND cj.codigo_juego = j.codigo "
                                   + "AND j.nombre = ? "
                                   + "AND c.numero = cc.numero_comentario");

            ps.setString(1, nomJuego);
            rsCom = ps.executeQuery();
           
            List<Comentario> listaCom = new ArrayList();

            while(rsCom.next()){

                if(rsCom.getBoolean(4) == false){ 
                //Si no es una respuesta creo el comentario, le seteo el numero y lo agrego.

                    Comentario com = new Comentario(rsCom.getString(2), new PDate(rsCom.getString(3)), rsCom.getString(5), nomJuego);
                    com.setNumero(rsCom.getInt(1));
                    listaCom.add(com);

                }

                else{
                //Si es una respuesta creo el comentario, le seteto el numero, el numpadre y lo agrego.

                    Comentario com = new Comentario(rsCom.getString(2), new PDate(rsCom.getString(3)), rsCom.getString(5), nomJuego);
                    com.setNumero(rsCom.getInt(1));
                    com.setRespuesta(getIDPadre(com));
                    listaCom.add(com);

                }

            }

            
            
            
            
            //Obtengo el Desarrollador del Juego
            ps = ct.getConexion().prepareStatement("SELECT d.nick, d.nombre, d.apellido, d.fechaNac, d.edad, "
                                   + "d.email, d.imagen, d.weblink "
                                   + "FROM desarrolladores_de_juegos dj, juegos j, "
                                   + " desarrolladores d "
                                   + " WHERE j.codigo = dj.codigo_juego "
                                   + " AND d.nick = dj.nick_desarrollador "
                                   + " AND j.nombre = ?");


            ps.setString(1, nomJuego);
            rsD = ps.executeQuery();

            
            
            Desarrollador d = new Desarrollador(rsD.getString(1), rsD.getString(2), 
                                  rsD.getString(3), rsD.getInt(5) , new PDate(rsD.getString(4)), 
                                  rsD.getString(6), rsD.getString(7), rsD.getString(8));

            j = new Juego(d, rsJ.getString(1), rsJ.getString(2), rsJ.getDouble(3), rsJ.getDouble(5), rsJ.getString(6));
            j.setCodigo(rsJ.getInt("codigo"));
            j.setCategorias(listaCat);
            j.setComentarios(listaCom);
            
        }
        
        catch(Exception e){
        
            throw e;
            
        }
        
        return j;
    
    }
    
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Juego.<br>
     * Lista todas las categorias del sistema para cargar un combobox.<br>
     *
     * @return List<Cliente>
     */
    public List<Cliente> getClientesCompranJuego(Integer codigo) throws Exception{
    
        
        
        List<Cliente> listaC = null;
        String nick, nom, ap, email, imagen;
        Integer edad;
        PDate fechaNac;
        //Cliente c = null;
        
        try{
            
            ps = ct.getConexion().prepareStatement("SELECT DISTINCT c.nick, c.nombre, c.apellido, c.fechaNac, "
                                   + "c.edad, c.email, c.imagen "
                                   + "FROM clientes c, clientes_compran_juegos ccj "
                                   + "WHERE ccj.codigo_juego = ? "
                                   + "AND c.nick = ccj.nick_cliente "
                                   + "ORDER BY c.nick");
            ps.setInt(1, codigo);
            rs = ps.executeQuery();
            listaC = new ArrayList();
            
            while(rs.next()){
                
                nick = rs.getString(1);
                nom = rs.getString(2);
                ap = rs.getString(3);
                edad = rs.getInt(5);
                email = rs.getString(6);
                imagen = rs.getString(7);
                fechaNac = new PDate(rs.getString(4));
                Cliente c = new Cliente(nick, nom, ap, edad, fechaNac, email, imagen);
                listaC.add(c); 
            
            }
            
        }catch(SQLException e){
            
            throw new Exception("ERROR en obtener los Clientes que compraron el Juego de codigo = " + codigo +".");
            
        }
        
        return listaC;
    
    }
 
    /**
     * Desarrollador: Nacho<br>
     * Operacion del Caso de Uso Consultar Reclamos.<br>
     * Lista todos los juegos del desarrollador nick.<br>
     *
     * @return List<Juego>
     */
    public List<Juego> getJuegosDesarrollador(String nick) throws Exception{
    
        List<Juego> listaJ = new ArrayList();
        
        try{
        
            //obtener los Juegos desarrollados por nick
            ps = this.ct.getConexion().prepareStatement(""
                       + " SELECT j.nombre, j.descripcion, j.size, j.codigo, j.precio, j.imagen " 
                       + " FROM juegos j, desarrolladores_de_juegos ddj " 
                       + " WHERE ddj.nick_desarrollador= ? " 
                       + " AND j.codigo = ddj.codigo_juego");
            ps.setString(1, nick);
            rs = ps.executeQuery();
            
            while(rs.next()){ //itero sobre el query
                Juego j = new Juego(null, rs.getString(1), rs.getString(2), rs.getDouble(3),rs.getDouble(5), rs.getString(6)); //nombre descripcion size codigo precio
                j.setCodigo(rs.getInt(4));

                ps = this.ct.getConexion().prepareStatement("SELECT * FROM desarrolladores WHERE nick='"+nick+"'"); ////OBTENGO EL DESARROLLADOR  -- nick nombre apellido fechaNac edad email imagen weblink
                ResultSet rs2 = ps.executeQuery(); 
                while(rs2.next()){ 

                    String nick1 = rs2.getString(1);
                    String nombre1 = rs2.getString(2);
                    String apellido1 = rs2.getString(3);
                    Integer edad1 = rs2.getInt(5);
                    PDate fecha1  = new PDate(rs2.getString(4));
                    String email1 =  rs2.getString(6);
                    String imagen1 =  rs2.getString(7);
                    String  weblink1 =  rs2.getString(8);
                    Desarrollador d = new Desarrollador(nick1, nombre1, apellido1, edad1, fecha1, email1, imagen1, weblink1);
                    j.setDesarrollador(d);

                }
                /*Agrego las categorias al Juego*/
                ps = this.ct.getConexion().prepareStatement("SELECT DISTINCT c.id_categoria, c.nombre FROM categorias_de_juegos cj, categorias c"
                        + " where cj.codigo_juego ="+j.getCodigo()+" AND cj.id_categoria = c.id_categoria");
                rs2 = ps.executeQuery();
                while(rs2.next()){

                    Categoria c = new Categoria(rs2.getString(2));
                    c.setId(rs2.getInt(1));
                    j.agregarCategoria(c);

                }    
                
                listaJ.add(j);


            }
            
            if(listaJ.isEmpty()){

                return null;

            }            
            
        }
 
        catch(Exception e){
        
            throw e;
        
        }        
        
        return listaJ;
    
    }
    
    
    // AREA DE TRABAJO DE DIEGO  
        
    public void agregarCategoria(Categoria c) throws Exception{ //INSERTA UNA CATEGORIA //diego
        
        
        
        try{
            
            ps = ct.getConexion().prepareStatement("INSERT INTO Categorias (id_categoria, nombre) VALUES(?, ?)");
            ps.setString(1, null);
            ps.setString(2, c.getNombre());            
            ps.executeUpdate();
            
        }
        
        catch(SQLException e){
            
            throw new Exception("Error al agregar la categoria: "+e.getMessage());
            
        }
        
    }
    
    public void agregarJuego(Juego j) throws Exception{ //diego
             
        
        
        try{
            
            ps = this.ct.getConexion().prepareStatement("INSERT INTO juegos(nombre,descripcion,size, codigo, precio, imagen)"
                    +" VALUES(?,?,?,?,?,?)");
            ps.setString(1,j.getNombre()); 
            ps.setString(2, j.getDescripcion());
            ps.setDouble(3, j.getSize());
            ps.setString(4, null);
            ps.setDouble(5, j.getPrecio());
            ps.setString(6, j.getImagen());
            ps.executeUpdate();   
            //Buscamos el codigo del juego agregado
            ps = this.ct.getConexion().prepareStatement("SELECT codigo FROM juegos WHERE nombre = ?");
            ps.setString(1, j.getNombre());
            ResultSet query = ps.executeQuery();
            Integer CODIGO = 0;
            while(query.next()){
                
                CODIGO = query.getInt("codigo");
                               
            }
            /*Fase 2 - agregamos a Desarrollador_Juego (tabla relacion) */
            ps = this.ct.getConexion().prepareStatement("INSERT INTO desarrolladores_de_juegos(nick_desarrollador, codigo_Juego) "
                       + "VALUES(?,?)");                
            ps.setString(1, j.getDesarrollador().getNick());
            ps.setInt(2, CODIGO);
            ps.executeUpdate();
            /*fase 3 - agregamos a la tabla de Categoria_Juego (relacion) */
            /*debe tener al menos una categoria siguiendo el UML*/
            ListIterator<Categoria> it = j.getCategorias().listIterator(); //creo el iterador (parecido a PA)
            while(it.hasNext()){ //mientras tenga siguiente recorro la lista, nota no es necesario llamar al it->next() como en c++ (automatico)
                ps = this.ct.getConexion().prepareStatement("INSERT INTO categorias_de_juegos(id_categoria, codigo_juego)"
                   + " VALUES(?,?)");
                Categoria categoria  = it.next(); //igualo la categoria al next (osea al siguiente, parte de null el iterador)
                
                ps.setInt(1, categoria.getId());
                ps.setInt(2, CODIGO);
                ps.executeUpdate();
            }
        }
        
        catch(SQLException e){
            
            throw new Exception("Error al agregar el juego: "+e.getMessage());
            
        }
          
    }
    
    //diego
    public List<Juego> obtenerJuegos() throws Exception{ //si necesitan que Juegos tenga mas atributos seteados (por ejemplo las colecciones etc deben agregarlas aca
        /*Usada en caso de uso 6*/
        
        
        
        List<Juego> listaJ = new ArrayList();
       
        try{
        
            ps = this.ct.getConexion().prepareStatement("SELECT * FROM juegos");
            ResultSet query = ps.executeQuery(); //query para iterar sobre Juegos

            while(query.next()){ //itero sobre el query
                Juego j = new Juego(null, query.getString(1), query.getString(2), query.getDouble(3),query.getDouble(5), query.getString(6)); //nombre descripcion size codigo precio
                j.setCodigo(query.getInt(4));
                ps = this.ct.getConexion().prepareStatement("SELECT nick_desarrollador FROM desarrolladores_de_juegos WHERE codigo_juego="+j.getCodigo()); //busco el codigo del desarrollador               
                ResultSet query2 = ps.executeQuery();  //query para buscar el desarrollador de ESTE juego
                String  nick = null;
                while(query2.next()){
                    nick = query2.getString(1);
                }

                ps = this.ct.getConexion().prepareStatement("SELECT * FROM desarrolladores WHERE nick='"+nick+"'"); ////OBTENGO EL DESARROLLADOR  -- nick nombre apellido fechaNac edad email imagen weblink
                query2 = ps.executeQuery(); 
                while(query2.next()){ 

                    String nick1 = query2.getString(1);
                    String nombre1 = query2.getString(2);
                    String apellido1 = query2.getString(3);
                    Integer edad1 = query2.getInt(5);
                    PDate fecha1  = new PDate(query2.getString(4));
                    String email1 =  query2.getString(6);
                    String imagen1 =  query2.getString(7);
                    String  weblink1 =  query2.getString(8);
                    Desarrollador d = new Desarrollador(nick1, nombre1, apellido1, edad1, fecha1, email1, imagen1, weblink1);
                    j.setDesarrollador(d);

                }
                /*Agrego las categorias al Juego*/
                ps = this.ct.getConexion().prepareStatement("SELECT DISTINCT c.id_categoria, c.nombre FROM categorias_de_juegos cj, categorias c"
                        + " where cj.codigo_juego ="+j.getCodigo()+" AND cj.id_categoria = c.id_categoria");
                query2 = ps.executeQuery();
                while(query2.next()){


                    Categoria c = new Categoria(query2.getString(2));
                    c.setId(query2.getInt(1));
                    j.agregarCategoria(c);

                }
                /*Agrego las versiones*/     

                /*SI SE NECESITAN MAS ATRIBUTOS COMO POR EJEMPLO LA COLECCION DE COMPRAS PARA CADA JUEGO SE PUEDE AGREGAR POR ACA ANTES DEL add()*/
                listaJ.add(j);


            }
            
        }
        
        catch(Exception e){
        
            throw e;
        
        }
        
        return listaJ; 
        
    }
       
    public Juego buscarJuego(String juego) throws Exception{ //diego
        
        
        
        Juego j = null;
        
        try{
        
            ps = this.ct.getConexion().prepareStatement("SELECT * FROM juegos WHERE nombre = ?");
            ps.setString(1, juego);
            ResultSet query = ps.executeQuery();

            while(query.next()){
                /*Juego*/
                String desc = query.getString(2);
                Double size = query.getDouble(3);
                Integer codigo = query.getInt(4);
                Double precio = query.getDouble(5);
                String imagenJ = query.getString(6);
                String nombreJuego = query.getString(1);
                ps = this.ct.getConexion().prepareStatement("SELECT nick_desarrollador FROM desarrolladores_de_juegos WHERE codigo_juego= ?");
                ps.setInt(1, codigo);
                ResultSet query2 = ps.executeQuery();

                ps = this.ct.getConexion().prepareStatement("SELECT * FROM desarrolladores WHERE nick = ?");
                ps.setString(1, query2.getString(1));
                query2 = ps.executeQuery();
                /*Desarrollador*/
                String nick = query2.getString(1);
                String nombre = query2.getString(2);
                String apellido = query2.getString(3);
                PDate fechanac = new PDate(query2.getString(4));
                Integer edad = query2.getInt(5);
                String correo = query2.getString(6);
                String imagen = query2.getString(7);
                String weblink = query2.getString(8);
                Desarrollador desarrollador = new Desarrollador(nick, nombre, apellido, edad, fechanac, correo, imagen, weblink);       
                j = new Juego(desarrollador, nombreJuego, desc, size, precio, imagenJ);
                j.setCodigo(codigo);
            }
            
        }
        
        catch(Exception e){
        
            throw e;
        
        }
        
        return j;
        
    }
    
    public Juego buscarJuegoxCodigo(Integer ID) throws Exception{ //diego
        
        
        
        Juego j = null;
        
        try{
        
            ps = this.ct.getConexion().prepareStatement("SELECT * FROM juegos WHERE codigo = ?");
            ps.setInt(1, ID);
            ResultSet query = ps.executeQuery();

            while(query.next()){
                /*Juego*/

                String nombreJuego = query.getString(1);
                String desc = query.getString(2);
                Double size = query.getDouble(3);
                Integer codigo = query.getInt(4);
                Double precio = query.getDouble(5);
                String imagenJ = query.getString(6);

                ps = this.ct.getConexion().prepareStatement("SELECT nick_desarrollador FROM desarrolladores_de_juegos WHERE codigo_juego= ?");
                ps.setInt(1, codigo);
                ResultSet query2 = ps.executeQuery();

                ps = this.ct.getConexion().prepareStatement("SELECT * FROM desarrolladores WHERE nick = ?");
                ps.setString(1, query2.getString(1));
                query2 = ps.executeQuery();
                /*Desarrollador*/
                String nick = query2.getString("nick");
                String nombre = query2.getString(2);
                String apellido = query2.getString(3);
                PDate fechanac = new PDate(query2.getString(4));
                Integer edad = query2.getInt(5);
                String correo = query2.getString(6);
                String imagen = query2.getString(7);
                String weblink = query2.getString(8);

                Desarrollador desarrollador = new Desarrollador(nick, nombre, apellido, edad, fechanac, correo, imagen, weblink);       
                j = new Juego(desarrollador, nombreJuego, desc, size, precio, imagenJ);
                j.setCodigo(codigo);

            }  
        
        }
          
        catch(Exception e){
        
            throw e;
        
        }
        
        return j;
        
    }

    //diego
    public Categoria buscarCategoria(String nombre) throws Exception{ //devuelve una categoria con su lista de juegos como atributo de coleccion
        
        
        
        Categoria c = null;
        
        try{
            
            ps = this.ct.getConexion().prepareStatement("SELECT * FROM categorias WHERE nombre = ?");
            ps.setString(1, nombre);
            ResultSet query = ps.executeQuery();
             
            if(query.next()){
                    
                    c = new Categoria(query.getString(2)); 
                    c.setId(query.getInt(1));
                     
            }
        
        }
        
        catch (SQLException e){
            
            throw new Exception("ERROR en la busqueda de categoria.");
            
        }
        
        return c;
    
    }
    
    //diego
    public List<Categoria> obtenerCategorias() throws Exception{
        
        
        
        List<Categoria> cats = new ArrayList();
        
        try {
            
            ps = this.ct.getConexion().prepareStatement("SELECT * from categorias");
            ResultSet query = ps.executeQuery();
            
            while(query.next()){
               
                Categoria c = new Categoria(query.getString(2));
                c.setId(query.getInt(1));
                cats.add(c);
                
            }
            
        }
        
        catch (SQLException e) {
            
            throw new Exception("ERROR en la busqueda de categoria.");
            
        }
        
        return cats;
    }
    
    //diego
    public Boolean existeCategoria(String nomCategoria) throws Exception {
        
        
        
        Boolean existe = false;
        
        try {
        
            ps = this.ct.getConexion().prepareStatement("SELECT nombre FROM categorias WHERE nombre = ?");
            ps.setString(1, nomCategoria);
            ResultSet query = ps.executeQuery();
            
            while(query.next()){

                String nombre = query.getString("nombre");

                if(nomCategoria.equalsIgnoreCase(nombre)){

                    existe = true;
                    
                }
            }
           
            
            
        }
        
        catch (SQLException e) {
        
            throw new Exception("ERROR en la busqueda en determinar si la categoria existe.");
        
        }
        
        return existe;
                
    }
    
    //diego
    public Boolean existeJuego(String juego) throws Exception{
        
        
        
        Boolean existe = false;
        try {
            
            ps = this.ct.getConexion().prepareStatement("SELECT nombre FROM juegos WHERE nombre = ?");
            ps.setString(1, juego);
            ResultSet query = ps.executeQuery();
            while(query.next()){
            	
                String njuego = query.getString("nombre");
                if(juego.equalsIgnoreCase(njuego)){
                    
                    existe = true;
                    
                }
            }
        }
        
        catch (SQLException e) {
            
            throw new Exception("ERROR en la busqueda en determinar el juego existe.");
        
        }
        
        return existe;
    }
    
       /**
     * Desarrollador: Diego<br>
     * Operacion para el caso de uso Alta Version<br>
     * Obtiene una lista de juegos que tienen al menos una version de un determinado desarrollador.<br>
     * Tambien agrega la lista de versiones al respectivo juego (lo pasa como String)
     * @return List<DataJuegoVersion>
     */
    public List<DataJuegoVersion> listJuegoVersion(String nickDesarrollador) throws Exception{
        
        
        
        List<DataJuegoVersion> lista = new ArrayList();
        try{
            
            
            ps = ct.getConexion().prepareStatement("SELECT DISTINCT j.nombre, j.codigo FROM juegos j, desarrolladores_de_juegos dj, versiones_aprobadas v "
                    + " WHERE dj.nick_desarrollador ='"+nickDesarrollador+"' AND dj.codigo_juego = j.codigo AND v.codigo_juego = j.codigo "
                    + " AND v.codigo_juego = j.codigo AND v.codigo_juego NOT IN(SELECT vv.codigo_juego FROM versiones_pendientes vv);");
            ResultSet query = ps.executeQuery();
            while(query.next()){
                
                List<String> versiones = new ArrayList();
                String nombre_juego = query.getString(1);
                Integer codigo_juego = query.getInt(2);
                ps = ct.getConexion().prepareStatement("SELECT numero from versiones_aprobadas WHERE codigo_juego = ?");
                ps.setInt(1, codigo_juego);
                ResultSet query2 = ps.executeQuery();                
                
                while(query2.next()){
                    
                    String vs = query2.getString(1);
                    versiones.add(vs);
                    
                }
                DataJuegoVersion dv = new DataJuegoVersion(codigo_juego.toString()+"- "+nombre_juego, versiones);                
                lista.add(dv);
                
            }
            
            
        
        }
        
        catch(SQLException e){
            
            throw new Exception("Error al obtener la lista de juegos (versiones).<br><br>Codigo de Error: BDMJOLDJ<br>Mensaje: " + e.getMessage());
            
        }
        
        return lista;
        
    }
    
    public List<DataJuegoVersion> listJuegoVersion() throws Exception{
        
        
        
        List<DataJuegoVersion> lista = new ArrayList();
        try{
            
            
            ps = ct.getConexion().prepareStatement("SELECT DISTINCT j.nombre, j.codigo FROM juegos j, desarrolladores_de_juegos dj, versiones_aprobadas v "
                    + " WHERE dj.codigo_juego = j.codigo AND v.codigo_juego = j.codigo "
                    + " AND v.codigo_juego = j.codigo AND v.codigo_juego NOT IN(SELECT vv.codigo_juego FROM versiones_pendientes vv);");
            ResultSet query = ps.executeQuery();
            while(query.next()){
                
                List<String> versiones = new ArrayList<String>();
                String nombre_juego = query.getString(1);
                Integer codigo_juego = query.getInt(2);
                ps = ct.getConexion().prepareStatement("SELECT numero from versiones_aprobadas WHERE codigo_juego = ?");
                ps.setInt(1, codigo_juego);
                ResultSet query2 = ps.executeQuery();                
                
                while(query2.next()){
                                        
                    String vs = query2.getString(1);
                    versiones.add(vs);                    
                    
                }
                
                DataJuegoVersion dv = new DataJuegoVersion(codigo_juego.toString()+"-"+nombre_juego, versiones);                
                lista.add(dv);
                
            }
            
            
        
        }
        
        catch(SQLException e){
            
            throw new Exception("Error al obtener la lista de juegos (versiones).<br><br>Codigo de Error: BDMJOLDJ<br>Mensaje: " + e.getMessage());
            
        }
        
        return lista;
        
    }
    
    public List<DataJuego> obtenerJuegosPopulares() throws Exception{
        
        
        
        List<DataJuego> lista = new ArrayList();
        try{
            
            ps=ct.getConexion().prepareStatement("DROP VIEW IF EXISTS populares;");
            ps.executeUpdate();
            
            ps=ct.getConexion().prepareStatement("CREATE VIEW populares AS SELECT j.nombre, j.descripcion, j.size, j.codigo, j.precio, j.imagen, d.nick_desarrollador, count(*) as cantidad_compras FROM juegos j, desarrolladores_de_juegos d, clientes_compran_juegos c WHERE c.codigo_juego = j.codigo AND d.codigo_juego = j.codigo " +
                                   " GROUP BY j.nombre, j.descripcion, j.size, j.codigo, j.precio, j.imagen, d.nick_desarrollador " +
                                    " ORDER BY cantidad_compras DESC;");
            ps.executeUpdate();
            
            ps=ct.getConexion().prepareStatement("SELECT * FROM populares ORDER BY cantidad_compras DESC");
            ResultSet query = ps.executeQuery();
            ps = ct.getConexion().prepareStatement("SELECT AVG(cantidad_compras) as average FROM populares");
            ResultSet query2= ps.executeQuery();
            Double promedio = 1.0;
            
            while(query2.next()){
                
                promedio = query2.getDouble("average");
                               
            }
            
            while(query.next()){
                
                Double cantidad = query.getDouble("cantidad_compras");
                                
                if(cantidad>=promedio){
                    
                    String path = query.getString("imagen");
                    
                    DataJuego dj = new DataJuego(query.getString("nick_desarrollador"), query.getString("nombre"),
                        query.getString("descripcion"), query.getDouble("size"),
                        query.getInt("codigo"), query.getDouble("precio") , null, query.getString("imagen"), null);
                    lista.add(dj);
                
                }
            }
        }        
        catch(SQLException e){
            
            throw new Exception("Error en la obtension de juegos mas populares"+e.getMessage());
            
        }
        
        return lista;
    }
 
     /* Desarrollador: Diego<br>
     * 
     * agrega la imagen a la base de datos
     * 
     * @return void
     */
     public void agregarImagen(Integer codigo_juego, String path) throws Exception{
         
         
         
        try{

            ps=ct.getConexion().prepareStatement("UPDATE juegos SET imagen = ? WHERE codigo = ?;");
            ps.setString(1, path);
            ps.setInt(2, codigo_juego);
            ps.executeUpdate();             

        }  
        
        catch(SQLException e){

           throw new Exception("Error al agregar la imagen: "+e.getMessage());

        }
       
     }
     
     /**
     * Desarrollador: Diego<br>
     * 
     * Da de baja un juego,
     * quita en las tablas: juegos, categorias_de_juegos, reclamos / reclamos de juegos ,
     * comentarios_de_juegos, comentarios, comentarios_de_clientes
     * @return void
     */
     public void bajaDeJuego(Integer codigo_juego, List<DataComentario> comentarios) throws Exception{

         
         
         try{
             
             ps = this.ct.getConexion().prepareStatement("DELETE FROM juegos WHERE codigo = ?");
             ps.setInt(1, codigo_juego);
             ps.executeUpdate();
                 
             ps = ct.getConexion().prepareStatement("DELETE FROM desarrolladores_de_juegos WHERE codigo_juego = ?");
             ps.setInt(1, codigo_juego);
             ps.executeUpdate();
               
             ps = ct.getConexion().prepareStatement("DELETE FROM categorias_de_juegos WHERE codigo_juego = ?");
             ps.setInt(1, codigo_juego);
             ps.executeUpdate();
             
             ps = ct.getConexion().prepareStatement("DELETE FROM versiones_aprobadas WHERE codigo_juego = ?");
             ps.setInt(1, codigo_juego);
             ps.executeUpdate();
             
             ps = ct.getConexion().prepareStatement("DELETE FROM versiones_pendientes WHERE codigo_juego = ?");
             ps.setInt(1, codigo_juego);
             ps.executeUpdate();
             
             ps = ct.getConexion().prepareStatement("DELETE FROM versiones_rechazadas WHERE codigo_juego = ?");
             ps.setInt(1, codigo_juego);
             ps.executeUpdate();
             
             if(comentarios.size() > 0){
                 
                 ps = ct.getConexion().prepareStatement("DELETE FROM comentarios_de_juegos WHERE codigo_juego = ?");
                 ps.setInt(1, codigo_juego);
                 ps.executeUpdate();
                 
                 for(DataComentario dc : comentarios){

                    borrarComentarioDeJuego(dc.getNumero());
                    
                 }
             }
             ps = ct.getConexion().prepareStatement("DELETE FROM notificaciones WHERE codigo_juego = ?");
             ps.setInt(1, codigo_juego);
             ps.executeUpdate();
             
         }
         catch(SQLException e){
            
             throw new Exception("Error al dar de baja el juego: "+e.getMessage());
            
         }
      
     }
     
     public void borrarComentarioDeJuego(Integer numero_comentario) throws Exception{
         
         
         
         try{
             
             ps = ct.getConexion().prepareStatement("DELETE FROM comentarios_de_clientes WHERE numero_comentario = ?");
             ps.setInt(1, numero_comentario);
             ps.executeUpdate();
             
             ps = ct.getConexion().prepareStatement("DELETE FROM respuestas_de_comentarios WHERE numero_comentario_hijo = ?");
             ps.setInt(1, numero_comentario);
             ps.executeUpdate();
          
             ps = ct.getConexion().prepareStatement("DELETE FROM comentarios WHERE numero = ?");
             ps.setInt(1, numero_comentario);
             ps.executeUpdate();
             
         }
         catch(SQLException e){
            
             throw new Exception("Error al borrar los comentarios del juego: "+e.getMessage());
            
         }
         
     }
     
     public void actualizarTamanio(Integer codigo_juego, Double tamanio) throws Exception{
         
         try{
             
             ps = ct.getConexion().prepareStatement("UPDATE juegos SET size = ? WHERE codigo = ?");
             ps.setDouble(1, tamanio);
             ps.setInt(2, codigo_juego);
             ps.executeUpdate();
             
         }
         catch(SQLException e){
             
             throw new Exception("Error al actualizar el tamanio del juego: "+e.getMessage());
             
         }
         
     }
     
}
    
